package com.own.demo.lwf.utils.workUtils;

import com.alibaba.fastjson.JSONObject;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.util.*;

/**
 * xml与map相互转换工具类
 * 说明：接口入参DTO中字段只使用String,Map两种类型
 *
 * @author dengxj
 */
public class XmlMapUtil {
    /**
     * xml转map 不带属性
     *
     * @param xmlStr
     * @param needRootKey 是否需要在返回的map里加根节点键
     * @return Map
     * @throws DocumentException
     */
    public static Map xml2map(String xmlStr, boolean needRootKey) throws DocumentException {
        Document doc = DocumentHelper.parseText(xmlStr);
        Element root = doc.getRootElement();
        Map<String, Object> map = (Map<String, Object>) xml2map(root);
        if (ValidateUtil.isEmpty(root.elements()) && ValidateUtil.isEmpty(root.attributes())) {
            return map;
        }
        if (needRootKey) {
            //在返回的map里加根节点键（如果需要）
            Map<String, Object> rootMap = new HashMap<String, Object>();
            rootMap.put(root.getName(), map);
            return rootMap;
        }
        return map;
    }

    /**
     * xml转map 带属性
     *
     * @param xmlStr
     * @param needRootKey 是否需要在返回的map里加根节点键
     * @return Map
     * @throws DocumentException
     */
    public static Map xml2mapWithAttr(String xmlStr, boolean needRootKey) throws DocumentException {
        Document doc = DocumentHelper.parseText(xmlStr);
        Element root = doc.getRootElement();
        Map<String, Object> map = (Map<String, Object>) xml2mapWithAttr(root);
        if (ValidateUtil.isEmpty(root.elements()) && ValidateUtil.isEmpty(root.attributes())) {
            return map; //根节点只有一个文本内容
        }
        if (needRootKey) {
            //在返回的map里加根节点键（如果需要）
            Map<String, Object> rootMap = new HashMap<String, Object>();
            rootMap.put(root.getName(), map);
            return rootMap;
        }
        return map;
    }

    /**
     * xml转map 不带属性
     *
     * @param e
     * @return
     */
    private static Map xml2map(Element e) {
        Map map = new LinkedHashMap();
        List list = e.elements();
        if (!ValidateUtil.isEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                Element iter = (Element) list.get(i);
                List mapList = new ArrayList();

                if (!ValidateUtil.isEmpty(iter.elements())) {
                    Map m = xml2map(iter);
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    } else {
                        map.put(iter.getName(), m);
                    }
                } else {
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(iter.getText());
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(iter.getText());
                        }
                        map.put(iter.getName(), mapList);
                    } else {
                        map.put(iter.getName(), iter.getText());
                    }
                }
            }
        } else {
            map.put(e.getName(), e.getText());
        }
        return map;
    }

    /**
     * xml转map 带属性
     *
     * @param element
     * @return
     */
    private static Map xml2mapWithAttr(Element element) {
        Map<String, Object> map = new LinkedHashMap<String, Object>();

        List<Element> list = element.elements();
        List<Attribute> listAttr0 = element.attributes(); // 当前节点的所有属性的list
        for (Attribute attr : listAttr0) {
            map.put("@" + attr.getName(), attr.getValue());
        }
        if (!ValidateUtil.isEmpty(list)) {

            for (int i = 0; i < list.size(); i++) {
                Element iter = list.get(i);
                List mapList = new ArrayList();

                if (!ValidateUtil.isEmpty(iter.elements())) {
                    Map m = xml2mapWithAttr(iter);
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    } else {
                        map.put(iter.getName(), m);
                    }
                } else {

                    List<Attribute> listAttr = iter.attributes(); // 当前节点的所有属性的list
                    Map<String, Object> attrMap = null;
                    boolean hasAttributes = false;
                    if (!ValidateUtil.isEmpty(listAttr)) {
                        hasAttributes = true;
                        attrMap = new LinkedHashMap<String, Object>();
                        for (Attribute attr : listAttr) {
                            attrMap.put("@" + attr.getName(), attr.getValue());
                        }
                    }

                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            // mapList.add(iter.getText());
                            if (hasAttributes) {
                                if (null != attrMap) {
                                    attrMap.put("#text", iter.getText());
                                    mapList.add(attrMap);
                                }
                            } else {
                                mapList.add(iter.getText());
                            }
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            // mapList.add(iter.getText());
                            if (hasAttributes) {
                                if (null != attrMap) {
                                    attrMap.put("#text", iter.getText());
                                    mapList.add(attrMap);
                                }
                            } else {
                                mapList.add(iter.getText());
                            }
                        }
                        map.put(iter.getName(), mapList);
                    } else {
                        // map.put(iter.getName(), iter.getText());
                        if (hasAttributes) {
                            if (null != attrMap) {
                                attrMap.put("#text", iter.getText());
                                map.put(iter.getName(), attrMap);
                            }
                        } else {
                            map.put(iter.getName(), iter.getText());
                        }
                    }
                }
            }
        } else {
            // 根节点的
            if (!ValidateUtil.isEmpty(listAttr0)) {
                map.put("#text", element.getText());
            } else {
                map.put(element.getName(), element.getText());
            }
        }
        return map;
    }

    /**
     * map转xml map中没有根节点的键
     *
     * @param map
     * @param rootName
     * @throws DocumentException
     * @throws IOException
     */
    public static Document map2xml(Map<String, Object> map, String rootName) throws DocumentException, IOException {
        Document doc = DocumentHelper.createDocument();
        Element root = DocumentHelper.createElement(rootName);
        doc.add(root);
        map2xml(map, root);
        //System.out.println(doc.asXML());
        //System.out.println(formatXml(doc));
        return doc;
    }

    /**
     * map转xml map中含有根节点的键
     *
     * @param map
     * @throws DocumentException
     * @throws IOException
     */
    public static Document map2xml(Map<String, Object> map) throws DocumentException, IOException {
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        if (entries.hasNext()) { //获取第一个键创建根节点
            Map.Entry<String, Object> entry = entries.next();
            Document doc = DocumentHelper.createDocument();
            Element root = DocumentHelper.createElement(entry.getKey());
            doc.add(root);
            map2xml((Map) entry.getValue(), root);
            //System.out.println(doc.asXML());
            //System.out.println(formatXml(doc));
            return doc;
        }
        return null;
    }

    /**
     * map转xml
     *
     * @param map
     * @param body xml元素
     * @return
     */
    private static Element map2xml(Map<String, Object> map, Element body) {
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Object> entry = entries.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if (key.startsWith("@")) {    //属性
                body.addAttribute(key.substring(1, key.length()), value.toString());
            } else if ("#text".equals(key)) { //有属性时的文本
                body.setText(value.toString());
            } else {
                if (value instanceof List) {
                    List list = (List) value;
                    Object obj;
                    for (int i = 0; i < list.size(); i++) {
                        obj = list.get(i);
                        //list里是map或String，不会存在list里直接是list的，
                        if (obj instanceof Map) {
                            Element subElement = body.addElement(key);
                            map2xml((Map) list.get(i), subElement);
                        } else {
                            body.addElement(key).setText((String) list.get(i));
                        }
                    }
                } else if (value instanceof Map) {
                    Element subElement = body.addElement(key);
                    map2xml((Map) value, subElement);
                } else {
                    body.addElement(key).setText(value.toString());
                }
            }
            //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
        return body;
    }

    public static String formatXml(Document document) throws DocumentException, IOException {
        // 格式化输出格式
        OutputFormat format = OutputFormat.createPrettyPrint();
        //outputFormat.setSuppressDeclaration(true); //是否生产xml头
        //format.setEncoding("UTF-8");
        //是否换行 false 不换行
        format.setNewlines(false);
        //设置是否缩进 true 需要缩进 false 不需要缩进
        format.setIndent(false);

        StringWriter writer = new StringWriter();

        // 格式化输出流
        XMLWriter xmlWriter = new XMLWriter(writer, format);
        // 将document写入到输出流
        xmlWriter.write(document);
        xmlWriter.close();
        return writer.toString();
    }

    /**
     * 将map转换为xml，默认是第一个键为跟节点,map中必须要有跟节点
     *
     * @param map
     * @return
     * @throws DocumentException
     * @throws IOException
     */
    public static String mapToXml(Map<String, Object> map) throws DocumentException, IOException {
        return formatXml(map2xml(map));
    }

    /**
     * 将map转换为xml，指定跟节点名字
     *
     * @param map
     * @param rootName
     * @return
     * @throws DocumentException
     * @throws IOException
     */
    public static String mapToXml(Map<String, Object> map, String rootName) throws DocumentException, IOException {
        return formatXml(map2xml(map, rootName));
    }


    public static final String PARAM_MODE_INPUT = "INPUT";
    public static final String PARAM_MODE_OUTPUT = "OUTPUT";

    public static List<Map> convertParamXML2MapList(String mode, String paramXML) throws Exception {
        Map resultMap = xml2map(paramXML, false);

        List<Map> theParams = null;

        Object paramInMap = ((Map) resultMap.get(mode + "S")).get(mode);

        if (paramInMap instanceof Map) {
            theParams = new ArrayList();

            theParams.add((Map) paramInMap);
        } else {
            theParams = (List<Map>) paramInMap;
        }

        return theParams;
    }

    public static List convertParamXML2DTOList(String mode, String inputXml, String clzName) throws Exception {
        List<Map> paramMapList = convertParamXML2MapList(mode, inputXml);

        List paramDtos = new ArrayList();
        Object param = null;
        for (Map paramMap : paramMapList) {
            //调用map2beanNull方法，删除所有值为空的key
            param = map2beanNull(paramMap, Class.forName(clzName));

            //paramDtos.add(param);
            paramDtos.add(param);
        }

        return paramDtos;
    }

    /**
     * 解析XML指定节点下的节点内容],并存入List<Map<String, String>>
     *
     * @param xmlStr  xml
     * @param xmlPath 指定路径
     *                例如：遍历row里面所有的子节点并存入List，xmlPath输入： rows/row
     *                <root>
     *                <rows>
     *                <row>...</row>
     *                <row>...</row>
     *                <row>...</row>
     *                </rows>
     *                </root>
     * @return List
     * @throws DocumentException
     * @Author Tzr
     */
    /*public static List<Map<String, String>> xmlToList(String xmlStr, String xmlPath) throws DocumentException {
        List<Map<String, String>> outList = new ArrayList<>();
        // 获取document对象
        Document document = DocumentHelper.parseText(xmlStr);
            *//*
                获取xmlPath路径下的子节点
                1.  SelectNodes("xmlPath")   表示：从当前节点的儿子节点中选择名称为 xmlPath 的节点
                2.  SelectNodes("/xmlPath")  表示：从根节点的儿子节点中选择名称为 xmlPath 的节点
                3.  SelectNodes("//xmlPath") 表示：从任意位置的节点上选择名称为 xmlPath 的节点。
             *//*
        List<Element> list = document.getRootElement().selectNodes("//" + xmlPath);
        if (!ValidateUtil.isEmpty(list)) {
            for (Element element : list) {
                // 获取xmlPath子节点的集合
                List<Element> childs = element.elements();
                Map<String, String> map = new HashMap<>();
                int size = childs.size();
                if (size > 0) {
                    for (Element child : childs) {
                        map.put(child.getName(), ValidateUtil.isEmpty(child.getText()) ? "" : child.getText());
                    }
                } else {
                    continue;
                }
                outList.add(map);
            }
        }
        return outList;
    }*/

    /**
     * 参数map中含子结点的转换，子结点为bean或String
     *
     * @param //paramMap
     * @param //key
     * @param //clzName
     * @return
     * @throws Exception
     */
    /*public static List convertMap2DTOList(Map paramMap, String key, String clzName) throws Exception {
        List paramDtos = new ArrayList();

        Object valObj = paramMap.get(key);
        List subObjList = null;
        Object param = null;

        if (valObj instanceof List) {
            subObjList = (List) valObj;

            if (subObjList.get(0) instanceof Map) {
                for (int i = 0; i < subObjList.size(); i++) {
                    param = BeanMapConvertor.map2bean((Map) subObjList.get(i), Class.forName(clzName));
                    paramDtos.add(param);
                }
            } else {
                paramDtos = subObjList;
            }
        } else {
            if (valObj instanceof Map) {
                param = BeanMapConvertor.map2bean((Map) valObj, Class.forName(clzName));
            } else {
                param = valObj;
            }

            paramDtos.add(param);
        }

        return paramDtos;
    }*/

    //解析示例
    /*public static void main(String[] args) throws Exception {
        long begin = System.currentTimeMillis();

        //1.简单input
        String inputXml = "<DATA>" +
                "<INPUTS>" +
                "<INPUT>" +
                "<AAA229>11</AAA229>" +
                "<AAE139>11</AAE139>" +
                "<AAA309>11</AAA309>" +
                "</INPUT>" +
                "<INPUT>" +
                "<AAA229>110</AAA229>" +
                "<AAE139>110</AAE139>" +
                "<AAA309>110</AAA309>" +
                "</INPUT>" +
                "</INPUTS>" +
                "</DATA>";

//        Map resultMap = xml2map(inputXml, false);
//        List<Map> inputs = (List<Map>)((Map)resultMap.get("INPUTS")).get("INPUT");
//        System.out.println(resultMap);

        List inputDtos = convertParamXML2DTOList(PARAM_MODE_INPUT, inputXml, "cn.hsa.cts.transactioninterface.dto.Transaction1803InDTO");

//        System.out.println(inputDtos);

        //2.简单output
        String outputXml = "<DATA>" +
                "<OUTPUTS>" +
                "<OUTPUT>" +
                "<mdtrtareaAdmdvsCode>in-1-mdtrtareaAdmdvsCode</mdtrtareaAdmdvsCode>" +
                "<loclMedinsCodg>in-1-loclMedinsCodg</loclMedinsCodg>" +
                "<nhsaMedinsNo>in-1-nhsaMedinsNo</nhsaMedinsNo>" +
                "</OUTPUT>" +
                "</OUTPUTS>" +
                "</DATA>";

        List outputDtos = convertParamXML2DTOList(PARAM_MODE_OUTPUT, outputXml, "cn.hsa.cts.transactioninterface.dto.Transaction1603OutDTO");
//        System.out.println(outputDtos);


        //3.input下含子结点，子结点为dto（适用于解析结算参保省返回信息中的基金分项）
        String trans1602nInput = "<DATA>" +
                "<INPUTS>" +
                "<INPUT>"
                + "<mdtrtareaAdmdvsCode>1</mdtrtareaAdmdvsCode>"
                + "<insuplcAdmdvsCode>2</insuplcAdmdvsCode>"
                + "<filNo>3</filNo>"
                + "<psnMgtCode>4</psnMgtCode>"
                + "<ssn>5</ssn>"
                + "<name>6</name>"
                + "<gend>7</gend>"
                + "<naty>8</naty>"
                + "<brdy>9</brdy>"
                + "<begnDate>10</begnDate>"
                + "<expirDate>11</expirDate>"
                + "<insutype>12</insutype>"
                + "<psnType>13</psnType>"
                + "<sscCardno>14</sscCardno>"
                + "<cardSn>15</cardSn>"
                + "<opterId>16</opterId>"
                + "<prmmsg>17</prmmsg>"
                + "<specbizAppyType>18</specbizAppyType>"
                + "<akb044>"
                + "<ROW>"
                + "<aaa157>0101</aaa157>"
                + "<aaa160>01</aaa160>"
                + "<aad006>????????????????</aad006>"
                + "<aae187>809.01</aae187>"
                + "</ROW>"
//                + "<ROW>"
//                + "<aaa157>0102</aaa157>"
//                + "<aaa160>03</aaa160>"
//                + "<aad006>????????????????????</aad006>"
//                + "<aae187>18909.12</aae187>"
//                + "</ROW>"
                + "</akb044>"
                + "<diseCodg>20</diseCodg>"
                + "<diseName>21</diseName>"
                + "<addr>22</addr>"
                + "<con>23</con>"
                + "<tel>24</tel>"
                + "<trafoutMedinsName>25</trafoutMedinsName>"
                + "<reflRea>26</reflRea>"
                + "<hospOpnn>27</hospOpnn>"
                + "<resdOutRea>28</resdOutRea>"
                + "<resoutCity>29</resoutCity>"
                + "<valiFlag>30</valiFlag>"
                + "</INPUT>" +
                "<INPUT>"
                + "<mdtrtareaAdmdvsCode>31</mdtrtareaAdmdvsCode>"
                + "<insuplcAdmdvsCode>32</insuplcAdmdvsCode>"
                + "<filNo>33</filNo>"
                + "<psnMgtCode>34</psnMgtCode>"
                + "<ssn>35</ssn>"
                + "<name>36</name>"
                + "<gend>37</gend>"
                + "<naty>38</naty>"
                + "<brdy>39</brdy>"
                + "<begnDate>40</begnDate>"
                + "<expirDate>41</expirDate>"
                + "<insutype>42</insutype>"
                + "<psnType>43</psnType>"
                + "<sscCardno>44</sscCardno>"
                + "<cardSn>45</cardSn>"
                + "<opterId>46</opterId>"
                + "<prmmsg>47</prmmsg>"
                + "<specbizAppyType>48</specbizAppyType>"
                + "<akb044>"
                + "<ROW>"
                + "<aaa157>0201</aaa157>"
                + "<aaa160>01</aaa160>"
                + "<aad006>????????????????</aad006>"
                + "<aae187>809.01</aae187>"
                + "</ROW>"
//                + "<ROW>"
//                + "<aaa157>0202</aaa157>"
//                + "<aaa160>03</aaa160>"
//                + "<aad006>????????????????????</aad006>"
//                + "<aae187>18909.12</aae187>"
//                + "</ROW>"
                + "</akb044>"
                + "<diseCodg>50</diseCodg>"
                + "<diseName>51</diseName>"
                + "<addr>52</addr>"
                + "<con>53</con>"
                + "<tel>54</tel>"
                + "<trafoutMedinsName>55</trafoutMedinsName>"
                + "<reflRea>56</reflRea>"
                + "<hospOpnn>57</hospOpnn>"
                + "<resdOutRea>58</resdOutRea>"
                + "<resoutCity>59</resoutCity>"
                + "<valiFlag>60</valiFlag>"
                + "</INPUT>" +
                "<INPUT>"
                + "<mdtrtareaAdmdvsCode>61</mdtrtareaAdmdvsCode>"
                + "<insuplcAdmdvsCode>62</insuplcAdmdvsCode>"
                + "<filNo>63</filNo>"
                + "<psnMgtCode>64</psnMgtCode>"
                + "<ssn>65</ssn>"
                + "<name>66</name>"
                + "<gend>67</gend>"
                + "<naty>68</naty>"
                + "<brdy>69</brdy>"
                + "<begnDate>70</begnDate>"
                + "<expirDate>71</expirDate>"
                + "<insutype>72</insutype>"
                + "<psnType>73</psnType>"
                + "<sscCardno>74</sscCardno>"
                + "<cardSn>75</cardSn>"
                + "<opterId>76</opterId>"
                + "<prmmsg>77</prmmsg>"
                + "<specbizAppyType>78</specbizAppyType>"
                + "<akb044>"
                + "<ROW>"
                + "<aaa157>0301</aaa157>"
                + "<aaa160>01</aaa160>"
                + "<aad006>????????????????</aad006>"
                + "<aae187>809.01</aae187>"
                + "</ROW>"
                + "<ROW>"
                + "<aaa157>0302</aaa157>"
                + "<aaa160>03</aaa160>"
                + "<aad006>????????????????????</aad006>"
                + "<aae187>18909.12</aae187>"
                + "</ROW>"
                + "</akb044>"
                + "<diseCodg>80</diseCodg>"
                + "<diseName>81</diseName>"
                + "<addr>82</addr>"
                + "<con>83</con>"
                + "<tel>84</tel>"
                + "<trafoutMedinsName>85</trafoutMedinsName>"
                + "<reflRea>86</reflRea>"
                + "<hospOpnn>87</hospOpnn>"
                + "<resdOutRea>88</resdOutRea>"
                + "<resoutCity>89</resoutCity>"
                + "<valiFlag>90</valiFlag>"
                + "</INPUT>" +
                "</INPUTS>" +
                "</DATA>";

        //convertParamXML2DTOList(PARAM_MODE_INPUT, trans1602nInput, "cn.hsa.cts.transactioninterface.dto.Transaction1602InDTO");

        //3.input下含子结点，子结点为String,（适用于解析备案指定医院）
        String trans1602nInput2 = "<DATA>" +
                "<INPUTS>" +
                "<INPUT>"
                + "<trnsInptMdtrtareaAdmdvs>1</trnsInptMdtrtareaAdmdvs>"
                + "<trnsInptInsuplcAdmdvs>1</trnsInptInsuplcAdmdvs>"
                + "<filNo>1</filNo>"
                + "<psnNo>1</psnNo>"
                + "<certno>1</certno>"
                + "<name>1</name>"
                + "<gend>1</gend>"
                + "<naty>1</naty>"
                + "<brdy>1</brdy>"
                + "<begndate>1</begndate>"
                + "<enddate>1</enddate>"
                + "<insutype>1</insutype>"
                + "<psnType>1</psnType>"
                + "<mdtrtCertNo>1</mdtrtCertNo>"
                + "<mdtrtCertSn>1</mdtrtCertSn>"
                + "<opterName>1</opterName>"
                + "<prmmsg>1</prmmsg>"
                + "<outFilType>1</outFilType>"
                + "<filHospInfo>"
                + "<fixmedinsNo>5100011000001</fixmedinsNo>"
                + "<fixmedinsNo>5100011000002</fixmedinsNo>"
                + "<fixmedinsNo>5100011000003</fixmedinsNo>"
                + "</filHospInfo>"
                + "<disecode>1</disecode>"
                + "<disename>1</disename>"
                + "<addr>1</addr>"
                + "<coner>1</coner>"
                + "<tel>1</tel>"
                + "<trafoutMedinsName>1</trafoutMedinsName>"
                + "<reflRea>1</reflRea>"
                + "<hospOpnn>1</hospOpnn>"
                + "<liveOutRea>1</liveOutRea>"
                + "<resoutCity>1</resoutCity>"
                + "<valiFlag>1</valiFlag>"
                + "</INPUT>"
                + "<INPUT>"
                + "<trnsInptMdtrtareaAdmdvs>2</trnsInptMdtrtareaAdmdvs>"
                + "<trnsInptInsuplcAdmdvs>2</trnsInptInsuplcAdmdvs>"
                + "<filNo>2</filNo>"
                + "<psnNo>2</psnNo>"
                + "<certno>2</certno>"
                + "<name>2</name>"
                + "<gend>2</gend>"
                + "<naty>2</naty>"
                + "<brdy>2</brdy>"
                + "<begndate>2</begndate>"
                + "<enddate>2</enddate>"
                + "<insutype>2</insutype>"
                + "<psnType>2</psnType>"
                + "<mdtrtCertNo>2</mdtrtCertNo>"
                + "<mdtrtCertSn>2</mdtrtCertSn>"
                + "<opterName>2</opterName>"
                + "<prmmsg>2</prmmsg>"
                + "<outFilType>2</outFilType>"
                + "<filHospInfo>"
                + "<fixmedinsNo>5100011000004</fixmedinsNo>"
                + "<fixmedinsNo>5100011000005</fixmedinsNo>"
                + "</filHospInfo>"
                + "<disecode>2</disecode>"
                + "<disename>2</disename>"
                + "<addr>2</addr>"
                + "<coner>2</coner>"
                + "<tel>2</tel>"
                + "<trafoutMedinsName>2</trafoutMedinsName>"
                + "<reflRea>2</reflRea>"
                + "<hospOpnn>2</hospOpnn>"
                + "<liveOutRea>2</liveOutRea>"
                + "<resoutCity>2</resoutCity>"
                + "<valiFlag>2</valiFlag>"
                + "</INPUT>"
                + "<INPUT>"
                + "<trnsInptMdtrtareaAdmdvs>3</trnsInptMdtrtareaAdmdvs>"
                + "<trnsInptInsuplcAdmdvs>3</trnsInptInsuplcAdmdvs>"
                + "<filNo>3</filNo>"
                + "<psnNo>3</psnNo>"
                + "<certno>3</certno>"
                + "<name>3</name>"
                + "<gend>3</gend>"
                + "<naty>3</naty>"
                + "<brdy>3</brdy>"
                + "<begndate>3</begndate>"
                + "<enddate>3</enddate>"
                + "<insutype>3</insutype>"
                + "<psnType>3</psnType>"
                + "<mdtrtCertNo>3</mdtrtCertNo>"
                + "<mdtrtCertSn>3</mdtrtCertSn>"
                + "<opterName>3</opterName>"
                + "<prmmsg>3</prmmsg>"
                + "<outFilType>3</outFilType>"
                + "<filHospInfo>"
                + "<fixmedinsNo>5100011000006</fixmedinsNo>"
                + "</filHospInfo>"
                + "<disecode>3</disecode>"
                + "<disename>3</disename>"
                + "<addr>3</addr>"
                + "<coner>3</coner>"
                + "<tel>3</tel>"
                + "<trafoutMedinsName>3</trafoutMedinsName>"
                + "<reflRea>3</reflRea>"
                + "<hospOpnn>3</hospOpnn>"
                + "<liveOutRea>3</liveOutRea>"
                + "<resoutCity>3</resoutCity>"
                + "<valiFlag>3</valiFlag>"
                + "</INPUT>"
                + "</INPUTS>" +
                "</DATA>";


        //List<Transaction1602InDTO> trans1602inDtos2 = convertParamXML2DTOList(PARAM_MODE_INPUT, trans1602nInput2, "cn.hsa.cts.transactioninterface.dto.Transaction1602InDTO");
        //for (Transaction1602InDTO trans1602inDto2 : trans1602inDtos2) {
            //System.out.println(trans1602inDto2);

            //Map filHospInfo = trans1602inDto2.getFilHospInfo();
            //List<String> fixmedinsNos = XmlMapUtil.convertMap2DTOList(filHospInfo, "fixmedinsNo", "java.lang.String");// convertParamXML2DTOList(PARAM_MODE_INPUT, filHospInfo, "java.lang.String");// XmlMapUtil.convertMap2DTOList(hospitalsMap, "fixmedinsNo", "java.lang.String");
           // for (String fixmedinsNo : fixmedinsNos) {
                //保存
                *//*System.out.println("fixmedinsNo: " + fixmedinsNo);*//*
           // }
        //}

        long end = System.currentTimeMillis();
        *//*System.out.println("used(ms): " + (end - begin));*//*
    }*/

    /**
     * 获取对应的map转xml类型
     * @param mapList
     * @return
     * @throws Exception
     */
    public static String getInputData(List<Map<String,Object>> mapList) throws Exception {
        Map<String,Object> mapInput = new HashMap();
        Map<String,Object> mapInputs = new HashMap();
        Map<String,Object> mapData = new HashMap();
        mapInput.put("INPUT",mapList);
        mapInputs.put("INPUTS",mapInput);
        mapData.put("DATA",mapInputs);
        String inputData = mapToXml(mapData);
        return inputData;
    }

    /**
     * dto转map
     * @param o
     * @return
     * @throws Exception
     */
    // public static Map<String,Object> dtoToMap(Object o) throws Exception {
    //     Map<String,Object> map = new HashMap();
    //     BeanMap beanMap = BeanMap.create(o);
    //     for (Object key : beanMap.keySet()){
    //         if (!ValidateUtil.isEmpty(beanMap.get(key))){
    //             map.put(camel2under(key+""),beanMap.get(key));
    //         }
    //     }
    //     return map;
    // }

    /**
     * 驼峰转换为全大写加_
     * @param c
     * @return
     */
    public static String camel2under(String c)
    {
        String separator = "_";
        c = c.replaceAll("([a-z])([A-Z])", "$1"+separator+"$2").toUpperCase();
        return c;
    }

    //型如XXX_YYY_ZZZ的子串改为xxxYyyZxx的子串
    private static String slashToFirstLetterUpper(String input) {
        String spliter = "_";
        StringBuffer output = new StringBuffer();
        String[] words = input.toLowerCase().split(spliter);
        for (int i = 0; i < words.length; i++) {
            if (i != 0) {
                output.append(fistLetterToUpper(words[i]));
            }
            else {
                output.append(words[i]);
            }
        }

        return output.toString();
    }
    private static String fistLetterToUpper(String input) {
        if (input == null)
            return "";
        if (input.length() <= 0)
            return "";

        return input.substring(0, 1).toUpperCase() + input.substring(1);
    }

    /**
     * map转dto
     * @param paramMap
     * @param c
     * @return
     */
    private static Object map2beanNull(Map<String,Object> paramMap, Class c) {
        StringBuffer buf = new StringBuffer();
        buf.append("{");
        for(Map.Entry<String,Object>  entry : paramMap.entrySet()){
            String mapKey = slashToFirstLetterUpper(entry.getKey());
            String mapValue = (String) entry.getValue();
            buf.append("'").append(mapKey).append("':'").append(mapValue).append("',");
        }
        String str = buf.substring(0,buf.length()-1).concat("}");
        Object o = JSONObject.parseObject(str,c);
        return o;
    }

    public static void main(String[] args) throws Exception {
        //OutAppyEvtDTO outAppyEvtDTO = new OutAppyEvtDTO();
        //outAppyEvtDTO.setPsnNo("1");
        //Map map = dtoToMap(outAppyEvtDTO);
        /*CurrentUser currentUser = new CurrentUser();
        currentUser.setName("hh");
        currentUser.setAdmDvs("12");
        HsafContextHolder.getContext().setCurrentUser(currentUser);
        ProvinceCallDTO provinceCallDTO = new ProvinceCallDTO();
        Map map = dtoToMap(provinceCallDTO);*/

        /*Map map = new HashMap();
        map.put("DATA_VER","0");
        map.put("CERTNO","22210011");
        map.put("DATA_VER","1");
        *//*Map map1 = new HashMap();
        map1.put("DATA_VER","1");
        map1.put("CERTNO","3123124");*//*
        List<Map<String,Object>> mapList = new ArrayList<>();
        mapList.add(map);
        //mapList.add(map1);
        String type = "下载类";
        String inputs = getInputData(mapList,type);
        System.out.println(inputs);*/

        /*String str = camel2under("DATA_VER");
        System.out.println(str);*/

        /*String outputXml = "<DATA>" +
                "<OUTPUTS>" +
                "<OUTPUT>" +
                "<MDTRTAREA_ADMDVS>1</MDTRTAREA_ADMDVS>" +
                "</OUTPUT>" +
                "</OUTPUTS>" +
                "</DATA>";
        List outputDtos = convertParamXML2DTOList(PARAM_MODE_OUTPUT, outputXml, "cn.hsa.mbs.personaltreatmentcheck.dto.OutAppyDownloadDTO");
        System.out.println(outputDtos);*/

        //String str = slashToFirstLetterUpper("DATA_VER");
        /*Map map = new HashMap();
        map.put("DATA_VER","0");
        map.put("CERTNO","22210011");
        map.put("DATA_VER","1");
        String str = map.toString();*/
        /*List<OutAppyEvtDTO> outAppyEvtDTOS = new ArrayList<>();
        OutAppyEvtDTO outAppyEvtDTO = new OutAppyEvtDTO();
        outAppyEvtDTO.setPsnNo("1");
        outAppyEvtDTOS.add(outAppyEvtDTO);
        String str = outAppyEvtDTOS.toString();*/
        /*Map<String,Object> map = new HashMap();
        map.put("EVT_SN","1");
        map.put("SERV_MATT_INSTID","1");
        map.put("SERV_MATT_NODE_INSTID","1");
        map.put("EVT_INST_ID","1");
        map.put("TRT_DCLA_DETL_SN","1");
        String str = "{";
        for(Map.Entry<String,Object>  entry : map.entrySet()){
            String mapKey = slashToFirstLetterUpper(entry.getKey());
            String mapValue = (String) entry.getValue();
            str = str+"'"+mapKey+"':'"+mapValue+"',";
        }
        str = str.substring(0,str.length()-1)+"}";
        Object o = JSONObject.parseObject(str,Class.forName("cn.hsa.mbs.personaltreatmentcheck.dto.OutAppyEvtDTO"));
        System.out.println(o);*/
        /*for (let i = 0; i < memoList.length; i++) {
            acctList[i] = memoList[i].key
            if (i == memoList.length - 1) {
                msg = msg + memoList[i].label + '。'
            } else {
                msg = msg + memoList[i].label + '、'
            }
        }
        acctMemoList[0] = msg
        acctMemoList[1] = JSON.stringify(acctList)
        dataReturn.memo = JSON.stringify(acctMemoList)*/
        /*["基本医疗上年账户、公务员历年账户。","[\"2\",\"6\"]"]*/
        /*String str = "";
        List<String> memoList = JSONObject.parseArray(str,String.class);
        System.out.println(memoList);*/
        /*Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("evtsn","1");
        OutAppyEvtDTO outAppyEvtDTO = (OutAppyEvtDTO) map2beanNull(paramMap,OutAppyEvtDTO.class);
        System.out.println(outAppyEvtDTO);*/
    }

}
